package cn.jlearn.proxy.server.handler.bs;

import cn.hutool.core.util.StrUtil;
import cn.jlearn.proxy.common.body.ClientConnectSuccessBody;
import cn.jlearn.proxy.common.container.SwitchContainer;
import cn.jlearn.proxy.common.enums.MsgTypeEnum;
import cn.jlearn.proxy.common.enums.ProtocolEnum;
import cn.jlearn.proxy.common.handler.AbstractBsHandler;
import cn.jlearn.proxy.common.packet.BsPacket;
import cn.jlearn.proxy.common.pojo.Constant;
import cn.jlearn.proxy.common.utils.NetUtil;
import cn.jlearn.proxy.server.container.ProxyServer;
import cn.jlearn.proxy.server.container.TcpForwardServer;
import cn.jlearn.proxy.server.utils.RedissonUtil;
import com.alibaba.fastjson.JSON;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;

import java.util.Collections;
import java.util.List;

/**
 * @author qianyingchao
 * @version 1.0
 * @date 2021/5/18 10:15 下午
 */
public class ClientConnectSuccessReqHandler extends AbstractBsHandler<ClientConnectSuccessBody> {

    @Override
    public Class<ClientConnectSuccessBody> bodyClass() {
        return ClientConnectSuccessBody.class;
    }

    @Override
    public void handler(BsPacket packet, ClientConnectSuccessBody bsBody, ChannelContext channelContext) throws Exception {
        String protocol;
        if (StrUtil.isBlank(bsBody.getProtocol())) {
            protocol = ProtocolEnum.HTTP.getCode();
        } else {
            protocol = bsBody.getProtocol();
        }
        String host;
        if (!ProtocolEnum.HTTP.getCode().equals(protocol)) {
            int port = NetUtil.getLocalPort();

            List<SwitchContainer> containers = Collections.singletonList(
                    new TcpForwardServer("0.0.0.0", port)
            );

            for (SwitchContainer container : containers) {
                Constant.SERVER_START_THREAD_POOL.execute(container::start);
            }

            host = bsBody.getHost() + ":" + port;
        } else {
            host = bsBody.getHost();
        }

        RedissonUtil.getInstance().set(host, bsBody.getToken());

        channelContext.set("host", host);
        channelContext.set("token", bsBody.getToken());

        Tio.bindBsId(channelContext, bsBody.getToken());

        ClientConnectSuccessBody body = new ClientConnectSuccessBody(bsBody.getToken(), host,
                bsBody.getProtocol(), bsBody.getBsId());
        BsPacket bsPacket = new BsPacket(MsgTypeEnum.TCP_CLIENT_CONNECT_SUCCESS_RES.getCode(), JSON.toJSONBytes(body));

        Tio.sendToBsId(ProxyServer.serverTioConfig, bsBody.getToken(), bsPacket);

    }

}
